package com.baseframe.sys.shiro;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.baseframe.common.utils.Constant;
import com.baseframe.sys.entity.FrameModule;
import com.baseframe.sys.entity.FrameUser;
import com.baseframe.sys.service.IFrameModuleService;
import com.baseframe.sys.service.IFrameUserRoleService;
import com.baseframe.sys.service.IFrameUserService;

/**
 * 认证
 * 
 */
@Component
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private IFrameModuleService frameModuleService;
    @Autowired
    private IFrameUserRoleService userRoleService;
    @Autowired
    private IFrameUserService userService;
    
    /**
     * 授权(验证权限时调用)
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		FrameUser user = (FrameUser)principals.getPrimaryPrincipal();
		String userId = user.getUserguid();
		
		List<String> permsList;
		
		//系统管理员，拥有最高权限
		if (userRoleService.hasRight(userId,Constant.SUPER_ADMIN_ROLE)) {
			List<FrameModule> menuList = frameModuleService.selectList();
			permsList = new ArrayList<>(menuList.size());
			for(FrameModule menu : menuList){
				permsList.add(menu.getPerms());
			}
		}else{
			//暂未实现
			permsList = new ArrayList<>();
			//permsList = sysUserDao.queryAllPerms(userId);
		}

		//用户权限列表
		Set<String> permsSet = new HashSet<>();
		for(String perms : permsList){
			if(StringUtils.isBlank(perms)){
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}
		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}

	/**
	 * 认证(登录时调用)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;

        //查询用户信息
		FrameUser user = new FrameUser();
		user = userService.findByLoginid(token.getUsername());
        
        //账号不存在
        if(user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),super.getName());
//        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
        return info;
	}

//	@Override
//	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
//		HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
//		shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
//		shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
//		super.setCredentialsMatcher(shaCredentialsMatcher);
//	}
	
	 /**
     * 认证密码匹配调用方法
     * @param authcToken  
     * @param info
     * @throws AuthenticationException
     */
    @Override
    protected void assertCredentialsMatch(AuthenticationToken authcToken,
                                          AuthenticationInfo info) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        
       DefaultPasswordEncoder dp=new DefaultPasswordEncoder("MD5");
		
		String inputpaswd=dp.encode(new String(token.getPassword()));
		if(inputpaswd.equals(info.getCredentials())){
			return;
		}else{
			String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials.";
            throw new IncorrectCredentialsException(msg);
		}
        // 若单点登录，则使用单点登录授权方法。
//        if (!token.getUsername().equals("thinkgem")) {
//            Map<String,Object> map = Maps.newConcurrentMap();
//            map.put("name",token.getUsername());    
//            map.put("pwd",String.valueOf(token.getPassword()));    
//            // 调用sso连接认证
//            String result = HttpClientUtils.doGet(Global.getConfig("ssoLoginUrl"),  map);
//            if (result.equals("true")){
//                return;
//            }
//        }
        // 否则还是继续匹配(兜底方案)
       // super.assertCredentialsMatch(token, info);
    }
}
